package com.wnhoo.smartfishtank.api;


import android.util.Log;

import com.wnhoo.smartfishtank.api.other.JSONUtil;
import com.wnhoo.smartfishtank.api.other.LM_ContantsPostKeyAPI;
import com.wnhoo.smartfishtank.util.MyLog;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by kevinwen on 2014/12/26.
 * Copyright (c) 2014/12/26.KevinWen. All rights reserved.
 */
public class LM_BasicAPI {

    private static final String tag = "LM_BasicAPI";

    private static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final String DATA_FORMAT = "json";
    public static final String BASE_JSON_URL = "http://www.wnhoo.com";
//    public static final String BASE_URL = "http://120.24.88.222/smart/";
    public static final String BASE_URL = "http://api.wnhoo.com/smart/";
    private static final String base_url_devices = BASE_URL + "devices/";
    private static final String base_url_sensors = BASE_URL + "sensors/";

    /**
     *OK? http://api.lemoniot.com/devices/add?token=**&device_id=**&title=**&type=**&timestamp=**
     *OK? http://api.lemoniot.com/devices/del?token=**&device_id=**&timestamp=**
     *OK？ http://api.lemoniot.com/devices/list?token=**&type=**&page=**&timestamp=**
     * http://api.lemoniot.com/devices/info?token=**device_id=**&timestamp=**
     * http://api.lemoniot.com/devices/info_edit?token=**device_id=**&title=**&about=**&type=**&timestamp=**
     *OK http://api.lemoniot.com/devices/online?token=**&device_id=**&timestamp=**
     *OK http://api.lemoniot.com/sensors/send_push?token=**&device_id=**&sensor_id=**&sensor_type=**&data=**&timestamp=**
     *OK http://api.lemoniot.com/sensors/receive?token=**&device_id=**&sensor_id=**&sensor_type=**&timestamp=**
     *OK？ http://api.lemoniot.com/sensors/history?token=**&device_id=**&sensor_id=**&sensor_type=**&page=**&timestamp=**
     */

    /**
     * 向硬件设备发送命令
     *
     * @param isDebug
     * @param deviceId
     * @param sensorId
     * @param sensorType
     * @param data
     * @param token_value
     * @return JSON String
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String requestSend(boolean isDebug,String deviceId,String sensorId,String sensorType,
                                   String data,String token_value ) throws ClientProtocolException, IOException {

        //http://api.lemoniot.com/sensors/send_push?token=**&device_id=**&sensor_id=**&sensor_type=**&data=**&timestamp=**
        //{"result":false,"error_code":409}
        String timestamp_value = new SimpleDateFormat(TIME_FORMAT).format(new Date());

        List<NameValuePair> parameterList = new ArrayList<NameValuePair>();
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_ACCESS_TOKEN, token_value));
        //parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, timestamp_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, "x"));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_ID, deviceId));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_SENSOR_ID, sensorId));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_SENSOR_TYPE, sensorType));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_CONTROL_DATA, data));
        String method = "send_push";
//        Log.i(tag, "------- 111 -------");
        return baseAPI(isDebug, base_url_sensors, method, parameterList);
    }

    /**
     * 接受硬件设备的消息
     *
     * @param isDebug
     * @param deviceId
     * @param sensorId
     * @param sensorType
     * @param token_value
     * @return JSON String or NULL
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String requestReceive(boolean isDebug,String deviceId,
                                     String sensorId,String sensorType,String token_value) throws ClientProtocolException, IOException,JSONException{

        //http://api.lemoniot.com/sensors/receive?token=**&device_id=**&sensor_id=**&sensor_type=**&timestamp=**
        //{"error_code":0,"value":"1,700","timestamp":"1419564070000"}

        String timestamp_value = new SimpleDateFormat(TIME_FORMAT).format(new Date());

        List<NameValuePair> parameterList = new ArrayList<NameValuePair>();
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_ACCESS_TOKEN, token_value));
        //parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, timestamp_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, "x"));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_ID, deviceId));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_SENSOR_ID, sensorId));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_SENSOR_TYPE, sensorType));

        String method = "receive";

        return baseAPI(isDebug, base_url_sensors, method, parameterList);
    }

    /**
     * 查看硬件设备是否在线和全状态
     *
     * @param isDebug
     * @param deviceId
     * @param token_value
     * @return JSON String
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String deviceOnlineStatus(boolean isDebug ,String deviceId,String token_value) throws ClientProtocolException, IOException,JSONException{

        //http://api.lemoniot.com/devices/online?token=**&device_id=**&timestamp=**
        //{"error_code":0,"id":"1005ACCF2337CB19","online":0,"full_status":"1,700"}
        String timestamp_value = new SimpleDateFormat(TIME_FORMAT).format(new Date());

        List<NameValuePair> parameterList = new ArrayList<NameValuePair>();
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_ACCESS_TOKEN, token_value));
        //parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, timestamp_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, "x"));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_ID, deviceId));

        String method = "online";

        return baseAPI(isDebug, base_url_devices, method, parameterList);
    }

    /**
     * 获取帐号下的设备的信息
     * 包括全状态和在线状态
     * page=0时，返回所有的数据记录
     * @param isDebug
     * @param token_value
     * @param device_type
     * @param page
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String deviceList(boolean isDebug ,String token_value,int device_type,int page) throws ClientProtocolException, IOException{

        String timestamp_value = new SimpleDateFormat(TIME_FORMAT).format(new Date());

        //http://api.lemoniot.com/devices/list?token=**&type=**&page=**&timestamp=**
        List<NameValuePair> parameterList = new ArrayList<NameValuePair>();
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_ACCESS_TOKEN, token_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_TYPE, device_type+""));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_PAGE, page+""));
        //parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, timestamp_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, "x"));

        String method = "list";
        String result = baseAPI(isDebug, base_url_devices, method, parameterList);
        MyLog.s(tag, result);
        return result;
    }

    /**
     * 把硬件设备从帐号下删除
     *
     * @param isDebug
     * @param deviceId
     * @param token_value
     * @return JSON String
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String deviceDel(boolean isDebug ,String deviceId,String token_value) throws ClientProtocolException, IOException{


        // http://api.lemoniot.com/devices/del?token=**&device_id=**&timestamp=**
        String timestamp_value = new SimpleDateFormat(TIME_FORMAT).format(new Date());

        List<NameValuePair> parameterList = new ArrayList<NameValuePair>();
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_ACCESS_TOKEN, token_value));
        //parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, timestamp_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, "x"));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_ID, deviceId));

        String method = "del";
        String result = baseAPI(isDebug, base_url_devices, method, parameterList);
        MyLog.s(tag, result);
        return result;
    }

    /**
     * 添加一个硬件设备到帐号下
     *
     * @param isDebug
     * @param deviceId
     * @param deviceType
     * @param token_value
     * @return JSON String
     * @throws ClientProtocolException
     * @throws IOException
     */
    protected static String deviceAdd(boolean isDebug ,String deviceId,int deviceType,String deviceTitle,String token_value) throws ClientProtocolException, IOException{

        // http://api.lemoniot.com/devices/add?token=**&device_id=**&title=**&type=**&timestamp=**
        //{"result":true,"error_code":0}

        String timestamp_value = new SimpleDateFormat(TIME_FORMAT).format(new Date());

        List<NameValuePair> parameterList = new ArrayList<NameValuePair>();
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_ACCESS_TOKEN, token_value));
        //parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, timestamp_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, "x"));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_ID, deviceId));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_TYPE, deviceType+""));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_TITLE, deviceTitle));
        String method = "add";
        String result = baseAPI(isDebug, base_url_devices, method, parameterList);
        MyLog.s(tag,result);
        return result;
    }

    /**
     * 修改一个设备的信息
     *
     * @param isDebug
     * @param deviceId
     * @param deviceType
     * @param token_value
     * @return JSON String
     * @throws ClientProtocolException
     * @throws IOException
     */
    protected static String deviceEdit(boolean isDebug ,String deviceId,int deviceType,String deviceTitle,String token_value) throws ClientProtocolException, IOException{

        // http://api.lemoniot.com/devices/add?token=**&device_id=**&title=**&type=**&timestamp=**
        //{"result":true,"error_code":0}

        String timestamp_value = new SimpleDateFormat(TIME_FORMAT).format(new Date());

        List<NameValuePair> parameterList = new ArrayList<NameValuePair>();
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_ACCESS_TOKEN, token_value));
        //parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, timestamp_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, "x"));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_ID, deviceId));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_TYPE, deviceType+""));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_TITLE, deviceTitle));
        String method = "info_edit";
        String result = baseAPI(isDebug, base_url_devices, method, parameterList);
        MyLog.s(tag,result);
        return result;
    }
    protected static String history(boolean isDebug ,String deviceId,String sensor_id,int sensor_type,int page ,String token_value) throws ClientProtocolException, IOException{

        // http://api.lemoniot.com/sensors/history?token=**&device_id=**&sensor_id=**&sensor_type=**&page=**&timestamp=**

        String timestamp_value = new SimpleDateFormat(TIME_FORMAT).format(new Date());

        List<NameValuePair> parameterList = new ArrayList<NameValuePair>();
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_ACCESS_TOKEN, token_value));
        //parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, timestamp_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_ID, deviceId));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_SENSOR_ID, sensor_id));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_SENSOR_TYPE, sensor_type+""));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_PAGE, page+""));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, "x"));

        String method = "history";
        String result = baseAPI(isDebug, base_url_sensors, method, parameterList);
        MyLog.s(tag,result);
        return result;
    }

    protected static String historyCount(boolean isDebug ,String deviceId,String sensor_id,int sensor_type,String token_value) throws ClientProtocolException, IOException{

        //120.24.225.120/smart/sensors/history_count?token=537ff238-18af-4dc6-bd84-40273ddc8388&device_id=1005ACCF2337CB19&sensor_id=S01&sensor_type=1&timestamp=x
        //{"error_code":0,"count":43}

        String timestamp_value = new SimpleDateFormat(TIME_FORMAT).format(new Date());

        List<NameValuePair> parameterList = new ArrayList<NameValuePair>();
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_ACCESS_TOKEN, token_value));
        //parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, timestamp_value));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_DEVICE_ID, deviceId));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_SENSOR_ID, sensor_id));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_SENSOR_TYPE, sensor_type+""));
        parameterList.add(new BasicNameValuePair(LM_ContantsPostKeyAPI.PARAMETER_TIMESTAMP, "x"));

        String method = "history_count";
        String result = baseAPI(isDebug, base_url_sensors, method, parameterList);
        MyLog.s(tag,result);
        return result;
    }

    /**
     * Http请求
     * @param isDebug
     * @param SERVERPATH
     * @param method
     * @param parameterList
     * @return JSON String
     * @throws ClientProtocolException
     * @throws IOException
     */
    protected static String baseAPI(boolean isDebug ,String SERVERPATH ,String method ,List<NameValuePair> parameterList) throws ClientProtocolException, IOException {

        return baseAPI(isDebug,SERVERPATH,method,parameterList,0,0);
    }
    /**
     * Http请求,可设置超时时间
     * @param isDebug
     * @param SERVERPATH
     * @param parameterList
     * @return JSON String
     * @throws ClientProtocolException
     * @throws IOException
     */
    protected static String baseAPI(boolean isDebug ,String SERVERPATH,List<NameValuePair> parameterList) throws ClientProtocolException, IOException {

        return baseAPI(isDebug,SERVERPATH,"",parameterList,0,0);
    }
    /**
     * Http请求,可设置超时时间
     * @param isDebug
     * @param SERVERPATH
     * @param method
     * @param parameterList
     * @param connection_timeout
     * @param so_timeout
     * @return JSON String
     * @throws ClientProtocolException
     * @throws IOException
     */
    private static String baseAPI(boolean isDebug ,String SERVERPATH ,String method ,List<NameValuePair> parameterList,long connection_timeout,long so_timeout) throws ClientProtocolException, IOException {
//        URL url = new URL(SERVERPATH+method);
//        //打开连接
//        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//        //设置提交方式
//        conn.setDoOutput(true);
//        conn.setDoInput(true);
//        conn.setRequestMethod("POST");
//        //post方式不能使用缓存
//        conn.setUseCaches(false);
//        conn.setInstanceFollowRedirects(true);
//        //设置连接超时时间
//        conn.setConnectTimeout(6*1000);
//        //配置本次连接的Content-Type，配置为application/x-www-form-urlencoded
//        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//        //维持长连接
//        conn.setRequestProperty("Connection", "Keep-Alive");
//        //设置浏览器编码
//        conn.setRequestProperty("Charset", "UTF-8");
//        DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
//        //将请求参数数据向服务器端发送
//        dos.write(new byte[]{0x01,0x02,0x03});
//        dos.flush();
//        dos.close();

        HttpClient httpclient = new DefaultHttpClient();
        HttpPost post = new HttpPost(SERVERPATH + method);
//        Log.i(tag,"baseAPI"+SERVERPATH + method);
        if(connection_timeout!=0)httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,connection_timeout);
        if(so_timeout!=0)httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,so_timeout);

        post.setEntity(new UrlEncodedFormEntity(parameterList, HTTP.UTF_8));

        HttpResponse response = httpclient.execute(post);
        HttpEntity entity = response.getEntity();

        String result = JSONUtil.getJSONString(entity);

        if(isDebug){
            StringBuffer tesmpSb = new StringBuffer(SERVERPATH + method);
            tesmpSb.append("?");
            for (NameValuePair tempNameValuePair : parameterList) {
                tesmpSb.append(tempNameValuePair.getName()).append("=").append(tempNameValuePair.getValue());
                tesmpSb.append("&");
            }
            MyLog.d(tag,tesmpSb.toString());
            MyLog.d(tag,"result->>>"+result);
        }
        return result;
    }
}
